package com.aia.prm;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.Assert;

import com.aia.prm.service.DefaultService;
import com.cfh.spring.MyContextLoaderListener;

class RealBeanFactory extends BeanFactory {
	private static final Logger logger = Logger.getLogger(BeanFactory.class);

	private boolean isWebApp = true;
	private static ApplicationContext app = null;

	private static Map<String, String> NameMap = new HashMap<String, String>();
	static {
		NameMap.put("com.sample.demo.ClassABC", "classABC");
	}

	RealBeanFactory() {
		super();
	}

	private String getBeanName(Class<?> clazz) {
		Assert.notNull(clazz);
		if (NameMap.containsKey(clazz.getName())) {
			return NameMap.get(clazz.getName());
		}
		String beanName = clazz.getSimpleName();
		if (beanName.length() == 1) {
			return beanName.toLowerCase();
		}
		return beanName.substring(0, 1).toLowerCase() + beanName.substring(1, beanName.length());
	}

	protected synchronized ApplicationContext getApplicationContext() {
		if (isWebApp) {
			ApplicationContext rez = MyContextLoaderListener.getWebApplicationContext();
			if (rez == null) {
				String msg = "Get null from MyContextLoaderListener.getWebApplicationContext()";
				logger.fatal(msg);
				throw new RuntimeException(msg);
			}
			return rez;
		} else {
			if (app == null) {
				synchronized (RealBeanFactory.class) {
					if (app == null) {
						logger.info("new ClassPathXmlApplicationContext");
						app = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
					}
				}
			}
			return app;
		}
	}

	public Object getBean(String str) {
		Assert.hasText(str);
		return getApplicationContext().getBean(str);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getBean(Class<? extends T> clazz) {
		Assert.notNull(clazz);
		String beanName = getBeanName(clazz);
		return (T) getApplicationContext().getBean(beanName, clazz);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getBean(String beanName, Class<? extends T> clazz) {
		return (T) getApplicationContext().getBean(beanName, clazz);
	}

	@Override
	public synchronized BeanFactory setWebApp(boolean argIsWebApp) {
		isWebApp = argIsWebApp;
		return this;
	}

	public Class getType(String s) {
		return getApplicationContext().getType(s);
	}

	@Override
	public DefaultService getDefaultService() {
		return (DefaultService) getBean("defaultService");
	}

	@Override
	public PlatformTransactionManager getPlatformTransactionManager() {
		return (PlatformTransactionManager) getBean("TransactionManager");
	}
}
